package org.hibernate.dao.impl;

import java.io.Serializable;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import org.apache.log4j.Logger;
import org.hibernate.Hibernate;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.SQLQuery;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.dao.IBaseDaobak;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

/**
 * 
 * @项目名称:cyj_trainer
 * @类名称:BaseDao
 * @类描述:统一的数据访问层实现类;
 * @创建人:苗有虎
 * @创建时间:Sep 18, 201010:07:12 AM
 * @修改人:Administrator
 * @修改时间:Sep 18, 201010:07:12 AM
 * @修改备注:
 * @version
 */
@SuppressWarnings("unchecked")
public class BaseDaobak extends HibernateDaoSupport implements IBaseDaobak {
	static Logger logger = Logger.getLogger(BaseDaobak.class.getName());

	/**
	 * 统计指定类的所有的持久化对象;
	 */
	public int countAll(String clazz) {
		final String hql = "select count(*) from " + clazz + " as a";
		Integer count = (Integer) this.getHibernateTemplate().execute(
				new HibernateCallback() {
					public Object doInHibernate(Session session)
							throws HibernateException {
						Query query = session.createQuery(hql);
						query.setMaxResults(1);
						int result = Integer.parseInt(query.uniqueResult()
								.toString());
						session.close();
						return result;
					}
				});
		return count.intValue();
	}

	/**
	 * 统计指定类的查询的结果;
	 */
	public int countQuery(String hql) {
		final String counthql = hql;
		Integer count = (Integer) this.getHibernateTemplate().execute(
				new HibernateCallback() {
					public Object doInHibernate(Session session)
							throws HibernateException {
						Query query = session.createQuery(counthql);
						query.setMaxResults(1);
						Object result = query.uniqueResult();
						int countResult = result != null ? Integer
								.parseInt(result.toString()) : 0;
						session.close();
						return countResult;
					}
				});
		return count.intValue();
	}

	public int countSqlQuery(String sql) {
		final String counthql = sql;
		Integer count = (Integer) this.getHibernateTemplate().execute(
				new HibernateCallback() {
					public Object doInHibernate(Session session)
							throws HibernateException {
						SQLQuery query = session.createSQLQuery(counthql);
						query.setMaxResults(1);
						Object result = query.uniqueResult();
						int countResult = result != null ? Integer
								.parseInt(result.toString()) : 0;
						session.close();
						return countResult;
					}
				});
		return count.intValue();
	}

	/**
	 * 删除指定ID的持久化对象;
	 */
	public void delById(Class clazz, Serializable id) {
		this.getHibernateTemplate().delete(
				this.getHibernateTemplate().load(clazz, id));
	}

	@SuppressWarnings("deprecation")
	/**
	 * 从连接池中取得一个JDBC的连接;
	 */
	public Connection getConnection() {
		return this.getHibernateTemplate().getSessionFactory()
				.getCurrentSession().connection();
	}

	/**
	 * 分页装载指定类的所有的持久化对象;
	 */
	public List listAll(String clazz, int pageNo, int pageSize) {
		final int pNo = pageNo;
		final int pSize = pageSize;
		final String hql = "from " + clazz + " as a";
		List list = this.getHibernateTemplate().executeFind(
				new HibernateCallback() {
					public Object doInHibernate(Session session)
							throws HibernateException, SQLException {
						Query query = session.createQuery(hql);
						query.setMaxResults(pSize);
						query.setFirstResult((pNo - 1) * pSize);
						List result = query.list();
						if (!Hibernate.isInitialized(result))
							Hibernate.initialize(result);
						session.close();
						return result;
					}
				});
		return list;
	}

	/**
	 * 装载指定类的所有的持久化对象;
	 */
	public List listAll(String clazz) {
		List list = this.getHibernateTemplate().find("from " + clazz + " as a");
		return list;
	}

	/**
	 * 加载指定ID的持久化对象;
	 */
	public Object loadById(Class clazz, Serializable id) {
		return this.getHibernateTemplate().get(clazz, id);
	}

	/**
	 * 加载满足条件的持久化对象;
	 */
	public Object loadObject(String hql) {
		final String hql1 = hql;
		Object obj = null;
		List list = this.getHibernateTemplate().executeFind(
				new HibernateCallback() {

					public Object doInHibernate(Session session)
							throws HibernateException, SQLException {
						Query query = session.createQuery(hql1);
						Object obj = query.list();
						session.close();
						return obj;
					}

				});
		if (list.size() > 0)
			obj = list.get(0);
		return obj;
	}

	/**
	 * 分页查询指定类的满足条件的持久化对象;
	 */
	public List query(String hql, int pageNo, int pageSize) {
		final int pNo = pageNo;
		final int pSize = pageSize;
		final String hql1 = hql;
		return this.getHibernateTemplate().executeFind(new HibernateCallback() {

			public Object doInHibernate(Session session)
					throws HibernateException, SQLException {
				Query query = session.createQuery(hql1);
				query.setMaxResults(pSize);
				query.setFirstResult((pNo - 1) * pSize);
				List result = query.list();
				if (!Hibernate.isInitialized(result))
					Hibernate.initialize(result);
				session.close();
				return result;
			}

		});
	}

	/**
	 * 查询指定类的满足条件的持久化对象(不带缓存);
	 */
	public List query(String hql) {
		final String hql1 = hql;
		return this.getHibernateTemplate().executeFind(new HibernateCallback() {

			public Object doInHibernate(Session session)
					throws HibernateException, SQLException {
				Query query = session.createQuery(hql1);
				Object obj = query.list();
				session.close();
				return obj;
			}
		});
	}

	/**
	 * 带有缓存的查询
	 */
	public List query(String hql, boolean cache) {
		final String hql1 = hql;
		final boolean cacheVlue = cache;
		return this.getHibernateTemplate().executeFind(new HibernateCallback() {

			public Object doInHibernate(Session session)
					throws HibernateException, SQLException {
				Query query = session.createQuery(hql1);
				query.setCacheable(cacheVlue);
				if (cacheVlue) {
					query.setCacheRegion("Forever");
				}
				Object obj = query.list();
				session.close();
				return obj;
			}
		});
	}

	/**
	 * 保存或更新指定的持久化对象;
	 */
	public void saveOrUpdate(Object obj) {
		this.getHibernateTemplate().save(obj);
	}

	/**
	 * 条件更新数据;
	 */
	public int update(String hql) {
		final String hql1 = hql;
		return ((Integer) this.getHibernateTemplate().execute(
				new HibernateCallback() {
					public Object doInHibernate(Session session)
							throws HibernateException, SQLException {
						Query query = session.createQuery(hql1);
						int result = query.executeUpdate();
						return result;
					}

				})).intValue();
	}

	/**
	 * 更新持久化对象
	 */
	public void update(Object obj) {
		this.getHibernateTemplate().saveOrUpdate(obj);
	}

	public List getPageBySql(Class cla, String sql, int pageNo, int pageSize) {
		return this.getAppSession().createSQLQuery(sql).addEntity(cla)
				.setFirstResult((pageNo - 1) * pageSize)
				.setMaxResults(pageSize).list();
	}

	/**
	 * 本查询是不带缓存的;
	 */
	public List getObjectBySQL(Class entity, String sql) {
		SQLQuery query = this.getAppSession().createSQLQuery(sql);
		query.addEntity(entity);
		return query.list();
	}

	/**
	 * 带有缓存的查询;
	 */
	public List getObjectBySQL(Class entity, String sql, boolean cache) {
		SQLQuery query = this.getAppSession().createSQLQuery(sql);
		query.addEntity(entity);
		query.setCacheable(cache);
		if (cache) {
			query.setCacheRegion("Forever");
		}
		return query.list();
	}

	// 根据相应的sql语句删除相应的对象
	public boolean delObjectBySQL(Class entity, String sql) {
		SQLQuery query = this.getAppSession().createSQLQuery(sql);
		query.addEntity(entity);
		int result = query.executeUpdate();
		return result > 0 ? true : false;
	}

	/**
	 * ***************************11.21号
	 * 底层DAO数据优化,添加运行事务************************************************
	 */
	/**
	 * 先清除缓存再获取
	 */
	public Object loadObjClearSessionFirst(Class<?> clazz, int id) {
		Session session = null;
		Transaction tx = null;
		try {
			session = this.getAppSession();
			tx = session.beginTransaction();
			session.clear();
			session.flush();
			Object obj = session.get(clazz, id);
			tx.commit();
			return obj;
		} catch (Exception e) {
			if (tx != null && tx.isActive() && !tx.wasRolledBack()) {
				tx.rollback();
			}
			logger.error(e.getMessage(), e);
		} finally {
			if (tx != null && tx.isActive() && !tx.wasCommitted()
					&& !tx.wasRolledBack()) {
				tx.commit();
			}
			tx = null;
		}
		return null;
	}

	/**
	 * 对数据进行加载操作
	 * 
	 * @param clazz
	 * @param id
	 * @return 返回要查询的对象
	 */
	public Object load(Class<?> clazz, int id) {
		Session session = null;
		Transaction tx = null;
		try {
			session = this.getAppSession();
			tx = session.beginTransaction();
			Object obj = session.get(clazz, id);
			tx.commit();
			return obj;
		} catch (Exception e) {
			if (tx != null && tx.isActive() && !tx.wasRolledBack()) {
				tx.rollback();
			}
			logger.error(e.getMessage(), e);
		} finally {
			if (tx != null && tx.isActive() && !tx.wasCommitted()
					&& !tx.wasRolledBack()) {
				tx.commit();
			}
			tx = null;
		}
		return null;
	}

	/**
	 * 进行数据保存操作
	 * 
	 * @param obj
	 * @return 返回传进的对象
	 */
	public Object save(Object obj) {
		Session session = null;
		Transaction tx = null;
		try {
			session = getAppSession();
			tx = session.beginTransaction();
			session.save(obj);
			tx.commit();
		} catch (Exception e) {
			if (tx != null && tx.isActive() && !tx.wasRolledBack()) {
				tx.rollback();
			}
			logger.error(e.getMessage(), e);
		} finally {
			if (tx != null && tx.isActive() && !tx.wasCommitted()
					&& !tx.wasRolledBack()) {
				tx.commit();
			}
			tx = null;
		}
		return obj;
	}

	public Object saveOrUpdateObj(Object obj) {
		Session session = null;
		Transaction tx = null;
		try {
			session = getAppSession();
			tx = session.beginTransaction();
			session.saveOrUpdate(obj);
			tx.commit();
		} catch (Exception e) {
			if (tx != null && tx.isActive() && !tx.wasRolledBack()) {
				tx.rollback();
			}
			logger.error(e.getMessage(), e);
		} finally {
			if (tx != null && tx.isActive() && !tx.wasCommitted()
					&& !tx.wasRolledBack()) {
				tx.commit();
			}
			tx = null;
		}
		return obj;
	}

	/**
	 * 进行数据保存操作
	 * 
	 * @param obj
	 * @return 返回传进的对象
	 */
	public Object updateObject(Object obj) {
		Session session = null;
		Transaction tx = null;
		try {
			session = getAppSession();
			tx = session.beginTransaction();
			session.update(obj);
			tx.commit();
		} catch (Exception e) {
			if (tx != null && tx.isActive() && !tx.wasRolledBack()) {
				tx.rollback();
			}
			logger.error(e.getMessage(), e);
		} finally {
			if (tx != null && tx.isActive() && !tx.wasCommitted()
					&& !tx.wasRolledBack()) {
				tx.commit();
			}
			tx = null;
		}
		return obj;
	}

	public boolean saveList(List<?> list) {
		if (list == null || list.size() == 0) {
			return true;
		}
		Session session = null;
		Transaction tx = null;
		try {
			session = getAppSession();
			tx = session.beginTransaction();
			for (Object obj : list) {
				session.save(obj);
			}
			tx.commit();
			return true;
		} catch (Exception e) {
			if (tx != null && tx.isActive() && !tx.wasRolledBack()) {
				tx.rollback();
			}
			logger.error(e.getMessage(), e);
		} finally {
			if (tx != null && tx.isActive() && !tx.wasCommitted()
					&& !tx.wasRolledBack()) {
				tx.commit();
			}
			tx = null;
		}
		return false;
	}

	/**
	 * 删除对象
	 * 
	 * @param obj
	 * @return
	 */
	public boolean deleteObj(Object obj) {
		Session session = null;
		Transaction tx = null;
		try {
			session = getAppSession();
			tx = session.beginTransaction();
			session.delete(obj);
			tx.commit();
			return true;
		} catch (Exception e) {
			if (tx != null && tx.isActive() && !tx.wasRolledBack()) {
				tx.rollback();
			}
			logger.error(e.getMessage(), e);
		} finally {
			if (tx != null && tx.isActive() && !tx.wasCommitted()
					&& !tx.wasRolledBack()) {
				tx.commit();
			}
			tx = null;
		}
		return false;
	}

	public boolean updateByHqlList(List<String> list) {
		if (list == null || list.size() == 0) {
			return true;
		}
		Session session = null;
		Transaction tx = null;
		try {
			session = getAppSession();
			tx = session.beginTransaction();
			for (String hql : list) {
				Query q = session.createQuery(hql);
				q.executeUpdate();
			}
			tx.commit();
			return true;
		} catch (Exception e) {
			if (tx != null && tx.isActive() && !tx.wasRolledBack()) {
				tx.rollback();
			}
			logger.error(e.getMessage(), e);
		} finally {
			if (tx != null && tx.isActive() && !tx.wasCommitted()
					&& !tx.wasRolledBack()) {
				tx.commit();
			}
			tx = null;
		}
		return false;
	}

	/**
	 * 如果数据库连接不成功,则进行5次重连
	 * 
	 * @param hql
	 * @param size
	 * @return
	 */
	public List<?> getTopList(String hql, int size) {
		Session session = null;
		Transaction tx = null;
		try {
			session = getAppSession();
			tx = session.beginTransaction();
			Query q = session.createQuery(hql);
			q.setMaxResults(size);
			List<?> list = q.list();
			tx.commit();
			return list;
		} catch (Exception e) {
			if (tx != null && tx.isActive() && !tx.wasRolledBack()) {
				tx.rollback();
			}
			logger.error(e.getMessage(), e);
		} finally {
			if (tx != null && tx.isActive() && !tx.wasCommitted()
					&& !tx.wasRolledBack()) {
				tx.commit();
			}
			tx = null;
		}
		return new ArrayList<Object>();
	}

	/**
	 * 获取当前的SESSION对象;
	 * 
	 * @return
	 */
	public Session getAppSession() {
		return this.getSessionFactory().getCurrentSession();
	}
}
